package com.yan.service;

import com.google.gson.Gson;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * @author yanheng
 * @data 2020/1/14 16:59
 */

@Component
public class Metrics {
    private Map<String, List<Double>> responseTimes = new HashMap<>();
    private Map<String, List<Double>> timestemps = new HashMap<>();

    private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    public void recordResponseTime(String apiName, double responseTime) {
        responseTimes.putIfAbsent(apiName, new ArrayList<>());
        responseTimes.get(apiName).add(responseTime);
    }

    public void recordTimestamp(String apiName, double timesTamp) {
        timestemps.putIfAbsent(apiName, new ArrayList<>());
        timestemps.get(apiName).add(timesTamp);
    }

    public void startRepeatReport(long period, TimeUnit unit) {
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Gson gson = new Gson();
                Map<String, Map<String, Double>> stats = new HashMap<>();
                for (Map.Entry<String, List<Double>> entry: responseTimes.entrySet()) {
                    String apiName = entry.getKey();
                    List<Double> apiRespTime = entry.getValue();
                    stats.putIfAbsent(apiName, new HashMap<>());
                    stats.get(apiName).put("max", max(apiRespTime));
                    stats.get(apiName).put("avg", max(apiRespTime));
                }

                for (Map.Entry<String, List<Double>> entry: timestemps.entrySet()) {
                    String apiName = entry.getKey();
                    List<Double> apiTimestamps = entry.getValue();
                    stats.putIfAbsent(apiName, new HashMap<>());
                    stats.get(apiName).put("count", (double) apiTimestamps.size());
                }
                System.out.println(gson.toJson(stats));
            }
        }, 0, period, unit);
    }

    private double max(List<Double> dateset){
        Double max = Double.MIN_VALUE;
        for (Double value : dateset) {
            max = Math.max(max, value);
        }
        return max;
    }
    private double avg(List<Double> dateset){
        if (dateset == null || dateset.size() == 0){
            return  0;
        }
        Double sum = 0D;
        for (Double value : dateset) {
            sum += value;
        }
        Double avg = sum / dateset.size();
        return avg;
    }

}
